package com.sky.service.user.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sky.constant.MessageConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.exception.LoginFailedException;
import com.sky.mapper.UserMapper;
import com.sky.service.user.UserService;
import com.sky.utils.HttpClientUtil;
import com.sky.utils.JwtUtil;
import com.sky.vo.UserLoginVO;
import com.sky.vo.UserReportVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        //1.发起微信登录 小程序发送过来openid
        // 调用微信接口服务，获取微信用户的openid
        String openid = getOpenid(userLoginDTO.getCode());

        //2.判断openid是否为null，就表示登录失败
        if (openid == null){
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }

        //3.如果openid不为null,就把openid当做用户的标识，准备往后台的user表存储
        User user = userMapper.findUserByOpenId(openid);
        log.info("查询user表指定openid的用户：{}",user);
        if (user == null){
            //如果是第一次登录，把用户信息存储到user表中
            user = new User();
            user.setOpenid(openid);
            user.setCreateTime(LocalDateTime.now());
            userMapper.insert(user);
        }
        //如果不是第一次登录，则表示已经用这个用户，直接登录成功
        //2.为小程序用户生成jwt令牌
        HashMap<String,Object> map = new HashMap<>();
        map.put("userId",user.getId());
        String token = JwtUtil.createJWT("weixin_token", 7200000, map);

        //3.将jwt令牌、用户信息返回给小程序端
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setId(user.getId());
        userLoginVO.setOpenid(user.getOpenid());
        userLoginVO.setToken(token);

        return userLoginVO;
    }

    /**
     * 统计指定时间段内新增用户的数量、用户的总数量
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userCount(LocalDate begin, LocalDate end) {
        //1.创建一个集合，存储这个时间段内每一天的日期对象
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }

        //2.获取每一种中的新增用户数，和用户总数
        List<Integer> newUserList = new ArrayList<>();
        List<Integer> totalUserList = new ArrayList<>();

        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            //获取这一天新增的用户数、获取总用户数
            Integer newUserCount = getUserCount(beginTime, endTime);
            Integer totalUserCount = getUserCount(null,endTime);

            newUserList.add(newUserCount);
            totalUserList.add(totalUserCount);
        }

        //3.封装返回结果
        UserReportVO userReportVO = UserReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .newUserList(StringUtils.join(newUserList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .build();

        return userReportVO;
    }

    /**
     * 根据时间区间统计用户数量
     * @param beginTime
     * @param endTime
     * @return
     */
    public Integer getUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
        Map map = new HashMap();
        map.put("begin",beginTime);
        map.put("end", endTime);
        return userMapper.countByMap(map);
    }

    /**
     * 调用微信接口服务，获取微信用户的openid
     * @param code
     * @return
     */
    private String getOpenid(String code){
        //微信服务接口地址
        String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";

        //调用微信接口服务，获得当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid","wxe8f5427bd5d532e0");
        map.put("secret","4be720199fe0520d642ff83fe920ecf8");
        map.put("js_code",code);
        map.put("grant_type","authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);

        JSONObject jsonObject = JSON.parseObject(json);
        String openid = jsonObject.getString("openid");
        return openid;
    }
}
